import os
from typing import Any, List

from fastapi import APIRouter
from jinja2 import Template

from Agent.Dispatch.Dao.DispatchRequest import DispatchRequest
from Agent.Dispatch.Dao.DispatchResponse import DispatchResponse
from Core.BaseAgent import BaseAgent
from LlmModel.DoubaoModel.DoubaoModel import DoubaoModel
from utils.logger import get_logger

logger = get_logger("DispatchAgent")


class DispatchService(BaseAgent):

    def __init__(self):
        super().__init__(name="DispatchAgent")
        self.name = "对话统筹与路由判断智能体"
        self.description = "负责依据对话上下文和当前博主消息，精准输出单个三位码用于路由"
        self.doubao_client = DoubaoModel()
        # self._setup_routes()

    # def _setup_routes(self) -> None:
    #     """设置路由"""
    #     router = APIRouter(prefix=f"/{self.__class__.__name__.lower().replace('agent', '')}")
    #     router.post("/dispatch", response_model=DispatchResponse)(self.dispatch_route)
    #     self.router = router
    async def process(self, input_data: Any) -> Any:
        """
        处理输入数据的核心方法，需要在子类中实现

        Args:
            input_data: 输入数据

        Returns:
            处理结果
        """
        pass

    def build_fill_bargin_dispatch_prompt(self, conversations: List, user_input: str) -> str | None:
        """
        构建路由判断提示词

        :param conversations: 聊天历史记录
        :return: 构建的提示词
        """
        try:
            # 读取 prompt 模板文件
            Parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
            prompt_file = os.path.join(Parent_dir, "Prompt", "fillAndBarginDispatch.txt")

            with open(prompt_file, 'r', encoding='utf-8') as f:
                prompt_template = Template(f.read())
            # 替换模板中的占位符

            prompt = prompt_template.render(
                conversations=conversations,
                user_input=user_input
            )
            # print("prompt:", prompt)

            return prompt

        except Exception as e:
            logger.error(f"读取 fillAndBarginDispatch.txt 文件失败: {str(e)}")

    def extract_route_code(self, response: str) -> str:
        """
        从模型响应中提取路由码

        :param response: 模型响应
        :return: 路由码（1或2）
        """
        # 清理响应，只保留数字
        cleaned_response = response.strip()

        # 提取第一个数字字符
        for char in cleaned_response:
            if char in ['1', '2', '3']:
                return char

        # 如果没有找到有效路由码，默认返回2
        return "2"

    async def fill_bargin_dispatch_route(self, data: DispatchRequest) -> DispatchResponse:
        """
        处理对话统筹与路由判断

        :param data: 包含聊天历史和当前输入的数据
        :return: 路由判断结果
        """
        try:

            conversations = data.conversations
            # 从最新的消息开始反向查找，找到第一个用户(user)发送的消息内容，如果找不到就返回空字符串
            user_input = next((m.get('content') for m in reversed(conversations) if m.get('role') == "user"), "")

            print("--------------------------------------------------\n")
            print(conversations)
            print(user_input)
            print("--------------------------------------------------\n")

            # 构建提示词
            prompt = self.build_fill_bargin_dispatch_prompt(conversations, user_input)

            # 调用大模型进行路由判断
            doubao_client = DoubaoModel()
            response = await doubao_client.generate_text(prompt)

            # 提取路由码
            route_code = self.extract_route_code(response)

            logger.info(f"路由判断完成, 路由码: {route_code}")

            return DispatchResponse(
                route_code=route_code,
                success=True,
                message="路由判断成功"
            )

        except Exception as e:
            logger.error(f"路由判断失败: {str(e)}")
            return DispatchResponse(
                route_code="2",  # 默认路由到咨询阶段
                success=False,
                message=f"路由判断失败: {str(e)}"
            )
